#pragma once

#include <exception>
#include <stdexcept>
#include "Globals.h"

namespace game_engine { namespace utils
{

/** The class Exception and its subclasses indicate conditions that a
reasonable application might want to catch.
*/
class Exception : public exception
{
///////////////////////////////////////////////////////////////////////////////
// Attribute definition
///////////////////////////////////////////////////////////////////////////////
private:
    enum { MSG_SIZE = 128 };
    char msg[MSG_SIZE + 1];

///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    Exception(const char* msg);
    Exception(const string& msg);
    Exception(const Exception& src);
    Exception& operator=(const Exception& src);
    ~Exception(void);

    // Others
    const char* what() const throw();

}; // class Exception

/** RuntimeException is the parent class of those exceptions that can be
thrown during the normal operation of the process.
*/
class RuntimeException : public Exception
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    RuntimeException(INT32 stat);
    RuntimeException(const string& msg);
    RuntimeException(const RuntimeException& msg);
    RuntimeException& operator=(const RuntimeException& src);
    ~RuntimeException(void);

private:
    static string formatMessage(INT32 stat);

}; // class RuntimeException

/** Thrown when an application attempts to use null in a case where an
object is required.
*/
class  NullPointerException : public RuntimeException
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    NullPointerException(const string& msg);
    NullPointerException(const NullPointerException& msg);
    NullPointerException& operator=(const NullPointerException& src);
    ~NullPointerException(void);

}; // class NullPointerException

/** Thrown to indicate that a method has been passed
an illegal or inappropriate argument.*/
class IllegalArgumentException : public RuntimeException
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
   IllegalArgumentException(const string& msg);
   IllegalArgumentException(const IllegalArgumentException&);
   IllegalArgumentException& operator=(const IllegalArgumentException&);
    ~IllegalArgumentException(void);

}; // class IllegalArgumentException

/** Signals that an I/O exception of some sort has occurred. This class
is the general class of exceptions produced by failed or interrupted
I/O operations.
*/
class IOException : public Exception
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    IOException(void);
    IOException(INT32 stat);
    IOException(const string& msg);
    IOException(const IOException &src);
    IOException& operator=(const IOException&);
    ~IOException(void);

private:
    static string formatMessage(INT32 stat);
};

class NoSuchElementException : public Exception 
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    NoSuchElementException(void);
    NoSuchElementException(const string& msg);
    NoSuchElementException(const NoSuchElementException&);
    NoSuchElementException& operator=(const NoSuchElementException&);
    ~NoSuchElementException(void);

};

class IllegalStateException : public Exception 
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    IllegalStateException(void);
    IllegalStateException(const IllegalStateException&);
    IllegalStateException& operator=(const IllegalStateException&);
    ~IllegalStateException(void);

};

class ParserException : public Exception 
{
///////////////////////////////////////////////////////////////////////////////
// Method definition
///////////////////////////////////////////////////////////////////////////////
public:
    // Constructors and Destructors
    ParserException(void);
    ParserException(const string &msg);
    ParserException(const ParserException&);
    ParserException& operator=(const ParserException&);
    ~ParserException(void);

};

}}
